/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "蒙皮骨骼.h"


C_蒙皮节点::C_蒙皮节点(S_设备环境& ctx) : C_节点基类(DEF_骨骼蒙皮节点, E_节点类型::e_节点Type_物体) {
	m_Ctx = ctx;
	f_setWName(u"蒙皮");

	C_插座基类* socket;
	DEF_创建物体插座_I(u"对象");
	DEF_创建骨架插座_I(u"骨骼");

	DEF_创建物体插座_O(u"对象");

	m_权重编辑 = f_alloc_BoolProp(nullptr, u"编辑权重");
	m_权重编辑.m_私有 = true;

	//m_权重计算 = f_alloc_BoolProp(nullptr, u"自动权重");
	//m_权重计算.m_私有 = true;
	m_权重计算 = f_alloc_EnumProp(nullptr,
	{
		{u"自动权重", u""},
		{u"封套权重", u""},
	}, u"权重计算方式");
	m_权重计算.m_私有 = true;
	f_prop_enum(m_权重计算) = 1;

	m_封套长度 = f_alloc_F32Prop(nullptr, u"封套缩放");
	m_封套长度.m_私有 = true;
	f_prop_F32(m_封套长度) = 1;
}

C_蒙皮节点::~C_蒙皮节点() {
	f_prop_Release(m_权重编辑);
	f_prop_Release(m_权重计算);
	f_prop_Release(m_封套长度);
}

bool C_蒙皮节点::f_update() {
	auto socket2 = f_get输入插座(2);

	auto* ob = DEF_物体插座数据(f_get输入插座(1), 0);
	auto* 骨架物体 = DEF_骨架插座数据(socket2, 0);

	//auto& outOb = *DEF_物体插座数据(f_get输出插座(1), 0);
	if (ob) {
		auto* mesh = f_ob_getMesh(ob, E_物体网格元素类型::e_MT_面);
		//f_buf_resize(mesh->m_蒙皮权重, mesh->m_顶点->m_Size * 4);
		//f_buf_resize(mesh->m_顶点对应骨骼ID, mesh->m_顶点->m_Size);
		//f_buf_resize(mesh->m_蒙皮权重, mesh->m_顶点->m_Mem.m_大小 * 4);
		//f_buf_resize(mesh->m_顶点对应骨骼ID, mesh->m_顶点->m_Mem.m_大小);
		
		if (socket2->f_isLink() && mesh) {
			bool 添加物体到骨骼 = true;
			for (auto& e : 骨架物体->m_子物体) {
				if (e == ob) {
					添加物体到骨骼 = false;
					break;
				}
			}
			if (添加物体到骨骼) {
				f_ob_add子物体(骨架物体, ob);
			}


			ob->m_骨架 = f_ob_from骨架(骨架物体);
			//f_ob_构建骨骼变换GPU数据(ob->m_骨架, 骨架物体);
			
			//f_surface_计算自动权重(mesh, f_ob_get变换矩阵(ob, ob->m_实例ID), ob->m_骨架, f_prop_F32(m_封套长度));
			auto mat = f_mat44_构建XYZ变换矩阵(ob->m_变换);
			//auto mat = f_mat44_identity();
			switch (f_prop_enum(m_权重计算)) {
				case 0: f_surface_计算自动权重(mesh, mat, ob->m_骨架, f_prop_F32(m_封套长度)); break;
				case 1: f_surface_计算封套权重(mesh, mat, ob->m_骨架->m_骨头物体, ob->m_骨架, f_prop_F32(m_封套长度)); break;
			}
			

			if (f_prop_Bool(m_权重计算)) {
			}
		}
		else {
			ob->m_骨架 = nullptr;
			ob->m_父对象 = nullptr;

			f_ob_从父物体中移除(ob);
			goto To_清除权重;
		}

		f_get输出插座(1)->f_setData(ob);
	}
	else {
		goto To_清除权重;
	}

	
	//if (f_prop_Bool(S_节点数据状态::g_打开编辑模式)) {
	//}
	//if (f_prop_Bool(m_权重编辑)) {
	//}
	

	return false;

	To_清除权重:
	f_get输出插座(1)->f_setData((void*)nullptr); 
	return false;
}

void C_蒙皮节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_权重计算, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_封套长度, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_蒙皮节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_权重计算, 块);
	f_prop_Save(m_封套长度, 块);
}

C_节点基类* f_node_创建蒙皮节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_蒙皮节点(ctx);
}

C_节点基类* f_node_加载蒙皮节点(S_设备环境& ctx, FILE* f) {
	C_蒙皮节点* node = new C_蒙皮节点(ctx);
	return node;
}

void f_node_保存蒙皮节点(C_节点基类* n, FILE* f) {
	C_蒙皮节点* node = dynamic_cast<C_蒙皮节点*>(n);
}













